home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / inventor / DirectManipRevoSurf / RevoSurfEngine.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  6.0 KB  |  209 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  * Copyright (C) 1994   Silicon Graphics, Inc.
  19.  *
  20.  _______________________________________________________________________
  21.  ______________  S I L I C O N   G R A P H I C S   I N C .  ____________
  22.  |
  23.  |   $Revision: 1.0 $
  24.  |
  25.  |   Classes:
  26.  |    RevoSurfEngine
  27.  |
  28.  |   Author(s)          : Paul Isaacs
  29.  |
  30.  ______________  S I L I C O N   G R A P H I C S   I N C .  ____________
  31.  _______________________________________________________________________
  32.  */
  33.  
  34. #include "RevoSurfEngine.h"
  35.  
  36. /////////////////////////////////////////////////////////////
  37. //  RevoSurfEngine
  38. //
  39. /////////////////////////////////////////////////////////////
  40. SO_ENGINE_SOURCE(RevoSurfEngine);
  41.  
  42.  
  43. void
  44. RevoSurfEngine::initClass()
  45. {
  46.     SO_ENGINE_INIT_CLASS(RevoSurfEngine, SoEngine, "Engine" );
  47. }
  48.  
  49. RevoSurfEngine::RevoSurfEngine()
  50. {
  51.     SO_ENGINE_CONSTRUCTOR(RevoSurfEngine);
  52.  
  53.     // Inputs:
  54.     // Two points that define axis to revolve around.
  55.     SO_ENGINE_ADD_INPUT(axisPt1,       (SbVec3f(0, 1, 0)));
  56.     SO_ENGINE_ADD_INPUT(axisPt2,       (SbVec3f(0, 0, 0)));
  57.  
  58.     // Coordinates that will be rotated about the axis.
  59.     SO_ENGINE_ADD_INPUT(profileCoords, (SbVec3f(0, 0, 0)));
  60.  
  61.     // Angle of rotation between successive columns of points.
  62.     SO_ENGINE_ADD_INPUT(angle,         (.3));
  63.  
  64.     // Outputs:
  65.     // This output is a grid of coordinates that comprise the surface
  66.     SO_ENGINE_ADD_OUTPUT(gridOfCoords,        SoMFVec3f);
  67.  
  68.     // Use this output if connecting to an SoIndexedFaceSet
  69.     // (This is better than SoQuadMesh if you want to see creases)
  70.     SO_ENGINE_ADD_OUTPUT(faceIndices,         SoMFLong);
  71.  
  72.     // Used to see if number of rows or columns changes.
  73.     oldVertsPerCol = 0;
  74.     oldVertsPerRow = 0;
  75. }
  76.  
  77. RevoSurfEngine::~RevoSurfEngine()
  78. {
  79. }
  80.  
  81. void
  82. RevoSurfEngine::evaluate()
  83. {
  84. #define MY_PI         3.14159
  85. #define MY_TWO_PI 2 * 3.14159
  86.  
  87.     // Get origin and direction of axis of rotation.
  88.     SbLine  rotAxis( axisPt1.getValue(), axisPt2.getValue() );
  89.     SbVec3f axisDir = rotAxis.getDirection();
  90.     SbVec3f axisPos = rotAxis.getPosition();
  91.  
  92.     // Calculate the angle of rotation in range between -PI and PI
  93.         float    rotAngle = angle.getValue();
  94.     // Avoid bad value
  95.         if (rotAngle == 0)
  96.         rotAngle = .1;
  97.     // Get angle between -PI and PI
  98.         while (rotAngle > MY_PI)
  99.         rotAngle -= MY_TWO_PI;
  100.         while (rotAngle < -MY_PI)
  101.         rotAngle += MY_TWO_PI;
  102.  
  103.     // Calculate numRows, numCols, numCoords 
  104.     // Add 1 for initial point, 
  105.     //   then add one for each rotation we can acheive before hitting 2PI.
  106.     //   then add 1 for final point.
  107.     long numCols = 1 + floor(MY_TWO_PI / fabs(rotAngle)) + 1;
  108.     long numRows = profileCoords.getNum();
  109.     long numCoords = numRows * numCols;
  110.     if ((numRows <= 1) || (numCols <= 1))
  111.         return;
  112.  
  113.     // Set size of scratch field. Use this to save memory between evaluations
  114.     scratchVecField.setNum( (int) numCoords );
  115.     SbVec3f *myVecs = scratchVecField.startEditing();
  116.  
  117.     // For each Column:
  118.     SbRotation colRot;
  119.     SbVec3f    thePt;
  120.     for (int col = 0; col < numCols; col++) {
  121.  
  122.         long curInd = col;
  123.  
  124.         // Calculate Rotation of points for this column.
  125.         // Final column is not rotated, however.
  126.         if (col != numCols - 1)
  127.             colRot.setValue( axisDir, rotAngle * col );
  128.         else
  129.             colRot.setValue( axisDir, 0 );
  130.  
  131.         // For each Row:
  132.         for (int row = 0; row < numRows; row++ ) {
  133.  
  134.             // Translate by -axisPos and undo this after the rotation.
  135.             // This makes rotation occur around axis instead of
  136.             // around origin.
  137.             thePt = profileCoords[row] - axisPos;
  138.  
  139.             // Rotate profile coord by rotation.
  140.             // Value is put into myVecs[curInd]
  141.             colRot.multVec( thePt, thePt );
  142.  
  143.             // Undo translation offset and assign into myVecs[curInd]
  144.             myVecs[curInd] = thePt + axisPos;
  145.  
  146.             curInd += numCols;
  147.         }
  148.     }
  149.  
  150.     // Set output values.
  151.     if (gridOfCoords.getNumConnections())
  152.         SO_ENGINE_OUTPUT(gridOfCoords,      SoMFVec3f,
  153.                      setValues(0,(int)numCoords,myVecs));
  154.  
  155.     // The faceIndices output contains indices for drawing surface as
  156.     // triangular faces.  
  157.     // It only changes if the number of rows or columns changes.
  158.     if ( oldVertsPerRow != numCols || oldVertsPerCol != numRows ) {
  159.         loadFaceIndices( numRows, numCols );
  160.         oldVertsPerRow = numCols;
  161.         oldVertsPerCol = numRows;
  162.     }
  163.  
  164. #undef MY_PI
  165. #undef MY_TWO_PI
  166. }
  167.  
  168. void
  169. RevoSurfEngine::loadFaceIndices( long numRows, long numCols )
  170. {
  171.     // Calculate and allocate proper number of longs 
  172.     long numTris = (numRows - 1) * (numCols - 1) * 2;
  173.     int  numLongs = (int) (4 * numTris);
  174.     long *myLongs = new long[numLongs];
  175.  
  176.     // For each topological upper row
  177.     long curUpLeft, curLowLeft, curLongInd = 0;
  178.     for (int row = 0; row < numRows - 1; row++ ) {
  179.         curUpLeft  = row * numCols; 
  180.         curLowLeft = curUpLeft + numCols;
  181.  
  182.         // For each topological left column
  183.         for (int col = 0; col < numCols - 1; col++ ) {
  184.  
  185.             // Indices for upper left triangle
  186.             myLongs[curLongInd++] = curUpLeft;
  187.             myLongs[curLongInd++] = curUpLeft + 1;
  188.             myLongs[curLongInd++] = curLowLeft;
  189.             myLongs[curLongInd++] = -1;
  190.  
  191.             // Indices for lower left triangle
  192.             myLongs[curLongInd++] = curLowLeft + 1;
  193.             myLongs[curLongInd++] = curLowLeft;
  194.             myLongs[curLongInd++] = curUpLeft + 1;
  195.             myLongs[curLongInd++] = -1;
  196.  
  197.             // Increment indices of corners.
  198.             curUpLeft++;
  199.             curLowLeft++;
  200.         }
  201.     }
  202.  
  203.     SO_ENGINE_OUTPUT(faceIndices,       SoMFLong,
  204.                  setValues(0, numLongs, myLongs));
  205.  
  206.     // Delete array of longs
  207.     delete [] myLongs;
  208. }
  209.